65.9K
CodeProject 正在变化。 阅读更多。
Home

AvalonDock [2.0] 教程第四部分 - 集成 AvalonEdit 选项

starIconstarIconstarIconstarIconstarIcon

5.00/5 (9投票s)

2013 年 4 月 1 日

CPOL

3分钟阅读

viewsIcon

64525

downloadIcon

1872

将 AvalonEdit 的文本编辑选项集成到 AvalonDock [2.0] 中

介绍 

AvalonDock [2.0] 系列文章仍在继续,您正在阅读第 4 部分。在本期中,我们将讨论在 AvalonEdit 中使用与文本相关的选项。这包括 WordWrap(自动换行)和行号显示的使用,并继续展示如何设置 AvalonEdit 以实现文本样式规则,例如,使用或不使用空格、制表符及其大小等。

 

先决条件  

如果您想跟随本文的讲解,请务必下载并继续使用上一个教程的第 3 步 [1] 中的示例。

自动换行和行号指示器

在本节中,我们将探讨如何在 AvalonEdit 中打开和关闭自动换行和行号显示。这种切换是通过命令处理程序完成的,该处理程序接受通过枚举定义的五个不同参数,我们使用 CLR 属性为视图提供显示每个设置当前状态的机会。我们首先调整文档视图模型中的新属性,然后添加一个新命令,最后再绑定到新属性。 

FileViewModel 类中添加一个 WordWrap ShowLineNumbers 布尔属性(我只展示 WordWrap,因为 ShowLineNumbers 非常相似) 

#region WordWrap
// Toggle state WordWrap
private bool mWordWrap = false;
public bool WordWrap
{
  get
  {
    return this.mWordWrap;
  }

  set
  {
    if (this.mWordWrap != value)
    {
      this.mWordWrap = value;
      this.RaisePropertyChanged("WordWrap");
    }
  }
}
#endregion WordWrap

在 Workspace 类中添加一个 WordWrap ShowLineNumbers 切换命令。此命令接受一个 ToggleEditorOption 枚举,该枚举也定义在 Workspace 类的命名空间中。此命令将在本文的后面部分进一步扩展。因此,这是枚举: 

  public enum ToggleEditorOption
  {
    WordWrap = 0,
    ShowLineNumber = 1,
    ShowEndOfLine = 2,
    ShowSpaces = 3,
    ShowTabs = 4
  }

这是新命令的代码

#region ToggleEditorOptionCommand
RelayCommand _toggleEditorOptionCommand = null;
public ICommand ToggleEditorOptionCommand
{
  get
  {
    if (this._toggleEditorOptionCommand == null)
    {
      this._toggleEditorOptionCommand = new RelayCommand((p) => OnToggleEditorOption(p),
                                                         (p) => CanToggleEditorOption(p));
    }

    return this._toggleEditorOptionCommand;
  }
}

private bool CanToggleEditorOption(object parameter)
{
  if (this.ActiveDocument != null)
    return true;

  return false;
}

private void OnToggleEditorOption(object parameter)
{
  FileViewModel f = this.ActiveDocument;

  if (parameter == null)
    return;

  if ((parameter is ToggleEditorOption) == false)
    return;

  ToggleEditorOption t = (ToggleEditorOption)parameter;

  if (f != null)
  {
    switch (t)
    {
      case ToggleEditorOption.WordWrap:
          f.WordWrap = !f.WordWrap;
        break;

      case ToggleEditorOption.ShowLineNumber:
          f.ShowLineNumbers = !f.ShowLineNumbers;
        break;

      default:
        break;
    }
  }
}
#endregion ToggleEditorOptionCommand

现在我们在 MainWindow.xaml 中添加一个 WordWrap ShowLineNumbers 按钮,为用户提供界面。使用 ToggleEditorOption 枚举需要在 XAML 中声明其命名空间

xmlns:vm="clr-namespace:Edi.ViewModel" 

这是两个按钮的声明:   

<ToggleButton ToolTip="Click this button to switch word wrap on or off"
              CommandParameter="{x:Static vm:ToggleEditorOption.WordWrap}"
              Command="{Binding ToggleEditorOptionCommand}"
              IsChecked="{Binding ActiveDocument.WordWrap, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}">
  <Image Height="32" Source="/Edi;component/Images/App/ShowWordWrap32.png" />
</Togglebutton>

<Togglebutton ToolTip="Click this button to switch display of line numbers on or off"
              CommandParameter="{x:Static vm:ToggleEditorOption.ShowLineNumber}"
              Command="{Binding ToggleEditorOptionCommand}"
              IsChecked="{Binding ActiveDocument.ShowLineNumbers, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}">
  <Image Height="32" Source="/Edi;component/Images/App/ShowLineNumbers32.png" />
</togglebutton>

在 MainWindow.xaml 的 AvalonEdit 语句中添加 WordWrap ShowLineNumbers 绑定

<avalonEdit:TextEditor
Document="{Binding Document, UpdateSourceTrigger=PropertyChanged}"
SyntaxHighlighting="{Binding HighlightDef}"
IsModified="{Binding Path=IsDirty, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
IsReadOnly="{Binding IsReadOnly}"
WordWrap="{Binding Path=WordWrap, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
ShowLineNumbers="{Binding Path=ShowLineNumbers, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">

        ...
</avalonEdit:TextEditor>

添加文本编辑选项支持

本节将介绍设置一些基本文本选项,例如空格和制表符的使用。

在 FileViewModel 类中添加一个 TextOptions 属性(注意 TextEditorOptions 类构造函数中的声明 - 它用两个空格替换制表符并将编辑器中的制表符关闭): 

#region TextEditorOptions
    private ICSharpCode.AvalonEdit.TextEditorOptions mTextOptions
      = new ICSharpCode.AvalonEdit.TextEditorOptions()
      {
        ConvertTabsToSpaces= false,
        IndentationSize = 2
      };

    public ICSharpCode.AvalonEdit.TextEditorOptions TextOptions
    {
      get
      {
        return this.mTextOptions;
      }

      set
      {
        if (this.mTextOptions != value)
        {
          this.mTextOptions = value;
          this.RaisePropertyChanged("TextOptions");
        }
      }
    }
#endregion TextEditorOptions

我们可以使用与之前相同的 ToggleEditorOptionCommand,通过扩展相应的枚举并在上面列出的 OnToggleEditorOption 方法中处理新情况: 

case ToggleEditorOption.ShowSpaces:
  f.TextOptions.ShowSpaces = !f.TextOptions.ShowSpaces;
  break;

case ToggleEditorOption.ShowTabs:
  f.TextOptions.ShowTabs = !f.TextOptions.ShowTabs;
  break;

case ToggleEditorOption.ShowEndOfLine:
  f.TextOptions.ShowEndOfLine = !f.TextOptions.ShowEndOfLine;
  break;

现在让我们将切换按钮添加到 MainWindow.xaml 工具栏中。您会注意到我们可以直接绑定到 TextOptions 属性的子属性。这使我们不必为每个设置实现另一个 FileViewModel 属性。 

<ToggleButton IsChecked="{Binding ActiveDocument.TextOptions.ShowEndOfLine, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
  Command="{Binding ToggleEditorOptionCommand}"
  CommandParameter="{x:Static vm:ToggleEditorOption.ShowEndOfLine}"
  ToolTip="Highlighted end of line in text (toggle on/off)">
  <Image Source="/Edi;component/Images/App/ShowEnter32.png" Height="32"/>
</ToggleButton>

<ToggleButton IsChecked="{Binding ActiveDocument.TextOptions.ShowSpaces, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
  Command="{Binding ToggleEditorOptionCommand}"
  CommandParameter="{x:Static vm:ToggleEditorOption.ShowSpaces}"
  ToolTip="Highlight spaces characters in text (toggle on/off)">

  <Image Source="/Edi;component/Images/App/ShowSpaces32.png" Height="32"/>
</ToggleButton>

<ToggleButton IsChecked="{Binding ActiveDocument.TextOptions.ShowTabs, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
  Command="{Binding ToggleEditorOptionCommand}"
  CommandParameter="{x:Static vm:ToggleEditorOption.ShowTabs}"
  ToolTip="Highlight tab characters in text (toggle on/off)">

  <Image Source="/Edi;component/Images/App/ShowTab32.png" Height="32"/>

</ToggleButton> 

在 MainWindow.xaml 绑定中添加一个文本选项属性

<avalonEdit:TextEditor
Document="{Binding Document, UpdateSourceTrigger=PropertyChanged}"
SyntaxHighlighting="{Binding HighlightDef}"
IsModified="{Binding Path=IsDirty, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
IsReadOnly="{Binding IsReadOnly}"
WordWrap="{Binding Path=WordWrap, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
ShowLineNumbers="{Binding Path=ShowLineNumbers, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Options="{Binding TextOptions}">
        ...

</avalonEdit:TextEditor> 

结论

使用 MVVM 与 AvalonDock [2.0] 和 AvalonEdit 并不难。我甚至已经启动了自己的存储库(如果您想贡献的话)https://github.com/Dirkster99/AvalonDock

下一部分将介绍更高级的功能,例如通过滚动条区域的组合框缩放字体(您可能在 Visual Studio 2010 中见过)。在那之后,我们将看看主题化,并解释如何使用我称之为“可主题化高亮”的技术来对超链接等项目进行主题化。

我希望收到您的反馈。如果您有其他意见,或者发现任何错误或误导之处,请告诉我。

历史

  • 2013.03.31 本文初稿
© . All rights reserved.